package tests;

import board.Board;
import board.DepthFirstSearch;
import board.Piece;
import list.ArrayList;

import player.Move;

public class WinningNetworkTests {
	public static void main(String[] args){
		checkTurnRule();
		checkMinLengthRule();
		checkBlocking();
		checkGetNetworkLengths();
		checkHomeAndGoalRow();
	}
	
	/**
	 * Checks the rule that a network must change direction when they connect. i.e. three pieces on the same line cannot be connected.
	 */
	public static void checkTurnRule(){
		Board b1 = new Board();
		b1.makeMove(new Move(5,0), Piece.BLACK);
		b1.makeMove(new Move(3,2), Piece.BLACK);
		b1.makeMove(new Move(1,4), Piece.BLACK);
		b1.makeMove(new Move(3,6), Piece.BLACK);
		b1.makeMove(new Move(6,6), Piece.BLACK);
		b1.makeMove(new Move(6,7), Piece.BLACK);
		ArrayList<Piece> b = DepthFirstSearch.hasWin(Piece.BLACK, b1); //should be false
		check("Checking turn rule for black: "+b, false, b!=null);
		 b = DepthFirstSearch.hasWin(Piece.WHITE, b1); //should be false
		check("Checking if white has a win: "+b, false, b!=null);
		
		b1.clearSpot(5, 0);
		b1.makeMove(new Move(1,0), Piece.BLACK);
		b = DepthFirstSearch.hasWin(Piece.BLACK, b1);
		check("Turning it into a winning configuration: "+b, true, b!=null); //should be true.
		
		
	}
	
	/**
	 * 	Checks whether a network has a minimum length of 6
	 */
	public static void checkMinLengthRule(){
		Board b1 = new Board();
		b1.makeMove(new Move(0,1), Piece.WHITE);
		b1.makeMove(new Move(1,2), Piece.WHITE);
		b1.makeMove(new Move(6,2), Piece.WHITE);
		b1.makeMove(new Move(6,5), Piece.WHITE);
		b1.makeMove(new Move(7,6), Piece.WHITE);
		ArrayList<Piece> b = DepthFirstSearch.hasWin(Piece.WHITE, b1);
		check("Checking min length rule: "+b, false, b!=null);
	}
	
	public static void checkBlocking(){
		Board b1 = new Board();
		b1.makeMove(new Move(2,0), Piece.BLACK);
		b1.makeMove(new Move(2,1), Piece.BLACK);
		b1.makeMove(new Move(5,1), Piece.BLACK);
		b1.makeMove(new Move(5,4), Piece.BLACK);
		b1.makeMove(new Move(2,4), Piece.BLACK);
		b1.makeMove(new Move(2,7), Piece.BLACK);
		ArrayList<Piece> b = DepthFirstSearch.hasWin(Piece.BLACK, b1);
		check("Making a winning configuration: "+b, true, b!=null);
		
		b1.makeMove(new Move(4,1), Piece.WHITE);
		b1.makeMove(new Move(5,3), Piece.WHITE);
		b = DepthFirstSearch.hasWin(Piece.BLACK, b1);
		//System.out.println(b);
		check("Blocking winning configuration: "+b, true, b==null);
	}
	
	public static void checkGetNetworkLengths(){
		Board b1 = new Board();
		b1.makeMove(new Move(2,0), Piece.BLACK);
		b1.makeMove(new Move(2,1), Piece.BLACK);
		b1.makeMove(new Move(5,1), Piece.BLACK);
		b1.makeMove(new Move(5,4), Piece.BLACK);
		b1.makeMove(new Move(2,4), Piece.BLACK);
		b1.makeMove(new Move(2,7), Piece.BLACK);
		ArrayList<Integer> i = DepthFirstSearch.getNetworkLengths(b1, Piece.BLACK);
		//System.out.println(i);
	}
	
	/**
	 * Check that you cannot use 2 pieces on the home or goal row to form a network
	 */
	public static void checkHomeAndGoalRow(){
		Board b1 = new Board();
		b1.makeMove(new Move(0,1), Piece.WHITE);
		b1.makeMove(new Move(2,1), Piece.WHITE);
		b1.makeMove(new Move(0,3), Piece.WHITE);
		b1.makeMove(new Move(3,3), Piece.WHITE);
		b1.makeMove(new Move(3,6), Piece.WHITE);
		b1.makeMove(new Move(7,6), Piece.WHITE);
		ArrayList<Piece> b = DepthFirstSearch.hasWin(Piece.WHITE, b1);
		check("Testing two pieces on home row: "+b, false, b!=null);
		
		 b1 = new Board();
			b1.makeMove(new Move(0,6), Piece.WHITE);
			b1.makeMove(new Move(1,6), Piece.WHITE);
			b1.makeMove(new Move(1,4), Piece.WHITE);
			b1.makeMove(new Move(7,4), Piece.WHITE);
			b1.makeMove(new Move(4,1), Piece.WHITE);
			b1.makeMove(new Move(7,1), Piece.WHITE);
			b = DepthFirstSearch.hasWin(Piece.WHITE, b1);
		check("Testing two pieces on goal row: "+b, false, b!=null);
	}

	static int count = 0;
	static void check(String test, Object expected, Object result){
		System.out.println(count+": " +test);
		System.out.flush();
		if( expected.equals(result)){
			System.out.println("\tpassed...");
			System.out.flush();
		}
		else{
			try{
				throw new RuntimeException(test+" failed");
			}
			catch(RuntimeException e){
				e.printStackTrace();
			}
		}
		count++;
	}
}
